package com.demo2do.core.utils;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
import au.com.bytecode.opencsv.bean.CsvToBean;

/**
 * 
 * @author Wilson
 */
public class CSVUtils {

    /**
     * read csv from inputstream and parse to list of beanClass according to columns, seperator, quote, startLine
     * 
     * @param inputStream    inputstream for reading csv
     * @param beanClass        target bean class
     * @param columns        bean properties' name e.g. ["name", "code", "createTime"]
     * @param seperator        
     * @param quote            
     * @param startLine        number of first line to read
     * @return
     */
    public static <T> List<T> toBeans(InputStream inputStream, Class<T> beanClass, String[] columns, char seperator, char quote, int startLine) {

        try {

            CSVReader reader = new CSVReader(new InputStreamReader(inputStream), seperator, quote, startLine);

            ColumnPositionMappingStrategy<T> strategy = new ColumnPositionMappingStrategy<T>();
            strategy.setType(beanClass);
            strategy.setColumnMapping(columns);

            CsvToBean<T> csvToBean = new CsvToBean<T>();
            return csvToBean.parse(strategy, reader);
            
        } catch (Exception e) {

        }
        
        return null;
    }

    /**
     * read csv from inputstream and parse to list of beanClass according to columns, startLine
     *         default using [,] as seperator, ['] as quote
     * 
     * @param inputStream
     * @param beanClass
     * @param columns
     * @param startLine
     * @return
     */
    public static <T> List<T> toBeans(InputStream inputStream, Class<T> beanClass, String[] columns, int startLine) {
        return toBeans(inputStream, beanClass, columns, ',', '\'', startLine);
    }

    /**
     * read csv from inputstream and parse to list of map accoording to keys, seperator, quote, startLine
     * 
     * @param inputStream    inputstream for reading csv
     * @param keys            keys in map, position in keys is the same as position of columns in csv
     * @param seperator
     * @param quote
     * @param startLine        number of first line of csv to read
     * @return
     */
    public static List<Map<String, String>> toMaps(InputStream inputStream, String[] keys, char seperator, char quote, int startLine) {

        // create listOfResult as a container to hold all map result
        List<Map<String, String>> listOfResult = new ArrayList<Map<String, String>>();

        try {

            // read all lines in csv using csv reader
            CSVReader reader = new CSVReader(new InputStreamReader(inputStream), seperator, quote, startLine);
            List<String[]> lines = reader.readAll();

            for(String[] line : lines) { // loop for each line in csv
                
                // create result map
                Map<String, String> result = new HashMap<String, String>();

                for(int i=0; i<keys.length; i++) { // loop for each item in one line

                    // put each <key, item> into result
                    result.put(keys[i], line[i]);
                
                }

                // add result to list
                listOfResult.add(result);
            }

            reader.close();
            
        } catch (Exception e) {
            
        }

        return listOfResult;
    }

    /**
     * read csv from inputstream and parse to list of map accoording to columns, startLine
     *         default using [,] as seperator, ['] as quote
     * 
     * @param inputStream
     * @param keys
     * @param startLine
     * @return
     */
    public static List<Map<String, String>> toMaps(InputStream inputStream, String[] keys, int startLine) {
        return toMaps(inputStream, keys, ',', '\'', startLine);
    }

}
